home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / DirTree 1.00 / source / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-30  |  49.1 KB  |  1,795 lines  |  [TEXT/KAHL]

  1. /* Main.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    File System Tree Viewer                                                */
  5. /*    Written by Thomas R. Lawrence, 1993 - 1994.                            */
  6. /*                                                                           */
  7. /*    This software is Public Domain; it may be used for any purpose         */
  8. /*    whatsoever without restriction.                                        */
  9. /*                                                                           */
  10. /*    This package is distributed in the hope that it will be useful,        */
  11. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  12. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   */
  13. /*                                                                           */
  14. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  15. /*                                                                           */
  16. /*****************************************************************************/
  17.  
  18. #include "MiscInfo.h"
  19. #include "Debug.h"
  20. #include "Audit.h"
  21. #include "Definitions.h"
  22.  
  23. #include "Main.h"
  24. #include "DirStuff.h"
  25. #include "EventLoop.h"
  26. #include "Memory.h"
  27. #include "Menus.h"
  28. #include "Alert.h"
  29. #include "GrowIcon.h"
  30. #include "StartupOpen.h"
  31. #include "DataMunging.h"
  32. #include "Numbers.h"
  33. #include "StringDialog.h"
  34.  
  35.  
  36. #define BoundingBoxThickness (2)
  37. #define LeadingLineThickness (4)
  38. #define TrailingLineThickness (4)
  39. #define FontPointSize (9)
  40. #define VerticalSeparationSpace (2)
  41. #define NumStatusLines (1)
  42. #define ScrollIncrement (20)
  43. #define AliasPattern (eMediumGrey)
  44. #define XLEAD (24)
  45.  
  46.  
  47. struct Node
  48.     {
  49.         Node*                        Next;
  50.         Node*                        Down;
  51.         char*                        Name;
  52.         DirFileTypes        Type;
  53.         OrdType                    InstanceWidth;
  54.         OrdType                    WhereX;
  55.         OrdType                    WhereY;
  56.         OrdType                    Width;
  57.         OrdType                    Height;
  58.         MyBoolean                SelectedFlag;
  59.         FileSpec*                Location;
  60.     };
  61.  
  62. struct AliasVec
  63.     {
  64.         AliasVec*                Next;
  65.         OrdType                    StartX;
  66.         OrdType                    StartY;
  67.         OrdType                    DisplaceX;
  68.         OrdType                    DisplaceY;
  69.     };
  70.  
  71.  
  72. static MyBoolean                    ErrorOccurredFlag = False;
  73. static Node*                            GlobalList;
  74. static OrdType                        TotalWidth;
  75. static OrdType                        TotalHeight;
  76. static AliasVec*                    ListOfAliases;
  77.  
  78. static Node*                            CurrentlyHilited = NIL;
  79. static Node*                            OtherOne = NIL;
  80. static long double                LastClickTime = 0;
  81. static OrdType                        LastClickX = -32767;
  82. static OrdType                        LastClickY = -32767;
  83. static MyBoolean                    AliasesOnTop = False;
  84. static MyBoolean                    ShowAliasLines = True;
  85. static char*                            SearchKey;
  86.  
  87. static OrdType                        CurrentXIndex;
  88. static OrdType                        CurrentYIndex;
  89.  
  90. static ScrollRec*                    VerticalScroll;
  91. static ScrollRec*                    HorizontalScroll;
  92. static WinType*                        Window;
  93. static OrdType                        LeadingSpace;
  94. static OrdType                        TextLineHeight;
  95.  
  96. static long                                DirectoryCount;
  97. static long                                FileCount;
  98. static long                                SymbolicLinkCount;
  99.  
  100. static MenuType*                    mmAppleMenu;
  101. static MenuType*                    mmFileMenu;
  102. static MenuType*                    mmEditMenu;
  103. static MenuItemType*            mAboutProgram;
  104. static MenuItemType*            mShowAliasesOnTop;
  105. static MenuItemType*            mShowAliasLines;
  106. static MenuItemType*            mClose;
  107. static MenuItemType*            mQuit;
  108. static MenuItemType*            mUndo;
  109. static MenuItemType*            mCut;
  110. static MenuItemType*            mCopy;
  111. static MenuItemType*            mPaste;
  112. static MenuItemType*            mClear;
  113. static MenuItemType*            mSelectAll;
  114. static MenuItemType*            mJumpSymbolicLink;
  115. static MenuItemType*            mReturnToPrevious;
  116. static MenuItemType*            mWhoLinksToThisOne;
  117. static MenuItemType*            mShowCurrentItem;
  118. static MenuItemType*            mGetFileInfo;
  119. static MenuItemType*            mFind;
  120. static MenuItemType*            mFindAgain;
  121.  
  122.  
  123. /* this recursively compiles a node list from a directory.  It does NOT */
  124. /* initialize the display positioning values. */
  125. Node*                            ListFromDirectory(FileSpec* Where)
  126.     {
  127.         DirectoryRec*        Directory;
  128.         Node*                        Start;
  129.         Node*                        Tail;
  130.         long                        Limit;
  131.         long                        Scan;
  132.  
  133.         RelinquishCPUJudiciouslyCheckCancel();
  134.         Directory = ReadDirectory(Where);
  135.         if (Directory == NIL)
  136.             {
  137.              MemOut0:
  138.                 ErrorOccurredFlag = True;
  139.                 return NIL;
  140.             }
  141.         ResortDirectory(Directory);
  142.         Limit = GetDirectorySize(Directory);
  143.         Start = NIL;
  144.         Tail = NIL;
  145.         for (Scan = 0; Scan < Limit; Scan += 1)
  146.             {
  147.                 Node*                        New;
  148.                 FileSpec*                Location;
  149.  
  150.                 RelinquishCPUJudiciouslyCheckCancel();
  151.                 New = (Node*)AllocPtrCanFail(sizeof(Node),"Node");
  152.                 New->SelectedFlag = False;
  153.                 if (New == NIL)
  154.                     {
  155.                      MemOut1:
  156.                         DisposeList(Start);
  157.                         DisposeDirectory(Directory);
  158.                         goto MemOut0;
  159.                     }
  160.                 New->Type = GetDirectoryEntryType(Directory,Scan);
  161.                 Location = GetDirectoryEntryFileSpec(Directory,Scan);
  162.                 if (Location == NIL)
  163.                     {
  164.                      MemOut2:
  165.                         ReleasePtr((char*)New);
  166.                         goto MemOut1;
  167.                     }
  168.                 New->Location = Location;
  169.                 if (New->Type == eDirectory)
  170.                     {
  171.                         DirectoryCount += 1;
  172.                         New->Down = ListFromDirectory(Location);
  173.                     }
  174.                 else if (New->Type == eSymbolicLink)
  175.                     {
  176.                         SymbolicLinkCount += 1;
  177.                         New->Down = NIL;
  178.                     }
  179.                 else
  180.                     {
  181.                         FileCount += 1;
  182.                         New->Down = NIL;
  183.                     }
  184.                 New->Name = GetDirectoryEntryName(Directory,Scan);
  185.                 if (New->Name == NIL)
  186.                     {
  187.                         DisposeFileSpec(New->Location);
  188.                         goto MemOut2;
  189.                     }
  190.                 New->Next = NIL;
  191.                 if (Tail != NIL)
  192.                     {
  193.                         Tail->Next = New;
  194.                     }
  195.                  else
  196.                     {
  197.                         Start = New;
  198.                     }
  199.                 Tail = New;
  200.             }
  201.         DisposeDirectory(Directory);
  202.         return Start;
  203.     }
  204.  
  205.  
  206. Node*                            ListFromDirectoryStart(FileSpec* Where)
  207.     {
  208.         Node*                        Root;
  209.         Node*                        Down;
  210.  
  211.         DirectoryCount = 0;
  212.         FileCount = 0;
  213.         SymbolicLinkCount = 0;
  214.         Root = (Node*)AllocPtrCanFail(sizeof(Node),"RootNode");
  215.         if (Root == NIL)
  216.             {
  217.                 PRERR(ForceAbort,"Not enough memory to continue.");
  218.             }
  219.         Root->SelectedFlag = False;
  220.         Root->Next = NIL;
  221.         if (Where != NIL)
  222.             {
  223.                 Root->Name = ExtractFileName(Where);
  224.                 Root->Location = DuplicateFileSpec(Where);
  225.             }
  226.          else
  227.             {
  228.                 Root->Location = GetRootFileSpec(); /* root doesn't really exist */
  229.                 Root->Name = StringToBlockCopy("/");
  230.             }
  231.         if (Root->Name == NIL)
  232.             {
  233.                 PRERR(ForceAbort,"Out of memory");
  234.             }
  235.         Down = ListFromDirectory(Where);
  236.         Root->Down = Down;
  237.         Root->Type = eDirectory;
  238.         return Root;
  239.     }
  240.  
  241.  
  242. void                            DisposeList(Node* List)
  243.     {
  244.         while (List != NIL)
  245.             {
  246.                 Node*                    Temp;
  247.  
  248.                 DisposeList(List->Down);
  249.                 Temp = List;
  250.                 List = List->Next;
  251.                 DisposeFileSpec(Temp->Location);
  252.                 ReleasePtr(Temp->Name);
  253.                 ReleasePtr((char*)Temp);
  254.             }
  255.     }
  256.  
  257.  
  258. /* this is used by ResolveAliases to find the actual location in the tree of */
  259. /* the thing that is referenced by an alias (Target is the file system's idea */
  260. /* of where, but that doesn't help us) */
  261. Node*                            FindMatchingItem(Node* List, FileSpec* Target,
  262.                                         OrdType* OutX, OrdType* OutY)
  263.     {
  264.         while (List != NIL)
  265.             {
  266.                 Node*                Temp;
  267.  
  268.                 if (CompareFileSpecs(Target,List->Location))
  269.                     {
  270.                         *OutX = List->WhereX + LeadingLineThickness;
  271.                         *OutY = List->WhereY + (List->Height / 2);
  272.                         return List;
  273.                     }
  274.                 Temp = FindMatchingItem(List->Down,Target,OutX,OutY);
  275.                 if (Temp != NIL)
  276.                     {
  277.                         return Temp;
  278.                     }
  279.                 List = List->Next;
  280.             }
  281.         return NIL;
  282.     }
  283.  
  284.  
  285. /* this scans the list and creates target vectors for all symbolic links */
  286. void                            ResolveAliases(Node* List)
  287.     {
  288.         while (List != NIL)
  289.             {
  290.                 if (List->Type == eSymbolicLink)
  291.                     {
  292.                         FileSpec*                    Target;
  293.  
  294.                         Target = DereferenceSymbolicLink(List->Location);
  295.                         if (Target != NIL)
  296.                             {
  297.                                 OrdType                    TargetX;
  298.                                 OrdType                    TargetY;
  299.  
  300.                                 if (FindMatchingItem(GlobalList,Target,&TargetX,&TargetY) != NIL)
  301.                                     {
  302.                                         AliasVec*                New;
  303.  
  304.                                         New = (AliasVec*)AllocPtrCanFail(sizeof(AliasVec),"AliasVec");
  305.                                         if (New != NIL)
  306.                                             {
  307.                                                 TargetX -= 1; /* just a bit before the box */
  308.                                                 New->StartX = List->WhereX + List->InstanceWidth;
  309.                                                 New->StartY = List->WhereY + (List->Height / 2);
  310.                                                 New->DisplaceX = TargetX - New->StartX;
  311.                                                 New->DisplaceY = TargetY - New->StartY;
  312.                                                 New->Next = ListOfAliases;
  313.                                                 ListOfAliases = New;
  314.                                             }
  315.                                     }
  316.                                 DisposeFileSpec(Target);
  317.                             }
  318.                          else
  319.                             {
  320.                                 EXECUTE(PRERR(AllowResume,"ResolveAliases:  symbolic link wasn't alias"));
  321.                             }
  322.                     }
  323.                 ResolveAliases(List->Down);
  324.                 List = List->Next;
  325.             }
  326.     }
  327.  
  328.  
  329. void                            DisposeAliasList(void)
  330.     {
  331.         while (ListOfAliases != NIL)
  332.             {
  333.                 AliasVec*                Temp;
  334.  
  335.                 Temp = ListOfAliases;
  336.                 ListOfAliases = ListOfAliases->Next;
  337.                 ReleasePtr((char*)Temp);
  338.             }
  339.     }
  340.  
  341.  
  342. /* this directory takes a list of directories which are assumed to be contained */
  343. /* within a single directory.  It then calculates the maximum width and height */
  344. /* needed to display the list and recursively sets up items contained in the dir. */
  345. void                            FillInSizeFields(Node* List, OrdType FrameX, OrdType FrameY,
  346.                                         OrdType* WidthOut, OrdType* HeightOut)
  347.     {
  348.         OrdType                    SlidingY;
  349.         OrdType                    Width;
  350.         OrdType                    Height;
  351.         Node*                        Scan;
  352.         OrdType                    OurMaxWidth;
  353.  
  354.         /* calculate size information for all contained items */
  355.         Scan = List;
  356.         SlidingY = FrameY + 1;
  357.         OurMaxWidth = 0;
  358.         while (Scan != NIL)
  359.             {
  360.                 OrdType                TempWidth;
  361.  
  362.                 /* figure out how wide each item is */
  363.                 ERROR((PtrSize(Scan->Name) > 32) || (PtrSize(Scan->Name) < 1),
  364.                     PRERR(AllowResume,"FillInSizeFields:  Filename is an invalid length"));
  365.                 TempWidth = LengthOfText(GetScreenFont(),FontPointSize,
  366.                     Scan->Name,PtrSize(Scan->Name),ePlain) + LeadingLineThickness
  367.                     + (2 * BoundingBoxThickness) + TrailingLineThickness;
  368.                 Scan->InstanceWidth = TempWidth;
  369.                 /* calculate item's variables */
  370.                 if (Scan->Down != NIL)
  371.                     {
  372.                         /* Scan has members, it's at least as high as it's first member... */
  373.                         FillInSizeFields(Scan->Down,FrameX + Scan->InstanceWidth,SlidingY,
  374.                             &Width,&Height);
  375.                     }
  376.                  else
  377.                     {
  378.                         /* Scan has no members, so it's one element high & itself wide */
  379.                         Width = 0;
  380.                         Height = TextLineHeight + VerticalSeparationSpace;
  381.                     }
  382.                 Scan->WhereX = FrameX;
  383.                 Scan->WhereY = SlidingY;
  384.                 Scan->Width = Scan->InstanceWidth + Width;
  385.                 Scan->Height = Height;
  386.                 if (OurMaxWidth < Scan->InstanceWidth + Width)
  387.                     {
  388.                         OurMaxWidth = Scan->InstanceWidth + Width;
  389.                     }
  390.                 SlidingY += Height;
  391.                 Scan = Scan->Next;
  392.             }
  393.         SlidingY += 1;
  394.         *WidthOut = OurMaxWidth;
  395.         *HeightOut = SlidingY - FrameY;
  396.     }
  397.  
  398.  
  399. /* redraw the tree */
  400. void                            RedrawArea(Node* List)
  401.     {
  402.         Node*                        Scan;
  403.  
  404.         Scan = List;
  405.         while (Scan != NIL)
  406.             {
  407.                 if (IsRectVisible(Window,Scan->WhereX - CurrentXIndex,Scan->WhereY
  408.                     + LeadingSpace - CurrentYIndex,Scan->Width,Scan->Height))
  409.                     {
  410.                         Patterns            How;
  411.  
  412.                         /* for each whole block that's visible, draw the root of the */
  413.                         /* block & all of it's members */
  414.                         if (Scan->SelectedFlag)
  415.                             {
  416.                                 DrawLine(Window,eBlack,Scan->WhereX + LeadingLineThickness
  417.                                     - CurrentXIndex + 1,Scan->WhereY + LeadingSpace
  418.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,
  419.                                     0,TextLineHeight);
  420.                                 DrawLine(Window,eBlack,Scan->WhereX + LeadingLineThickness
  421.                                     - CurrentXIndex + (Scan->InstanceWidth - LeadingLineThickness
  422.                                     - TrailingLineThickness) - 2,Scan->WhereY + LeadingSpace
  423.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,
  424.                                     0,TextLineHeight);
  425.                                 InvertedTextLine(Window,GetScreenFont(),FontPointSize,Scan->Name,
  426.                                     PtrSize(Scan->Name),Scan->WhereX + BoundingBoxThickness
  427.                                     + LeadingLineThickness - CurrentXIndex,Scan->WhereY + LeadingSpace
  428.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,ePlain);
  429.                             }
  430.                          else
  431.                             {
  432.                                 DrawLine(Window,eWhite,Scan->WhereX + LeadingLineThickness
  433.                                     - CurrentXIndex + 1,Scan->WhereY + LeadingSpace
  434.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,
  435.                                     0,TextLineHeight);
  436.                                 DrawLine(Window,eWhite,Scan->WhereX + LeadingLineThickness
  437.                                     - CurrentXIndex + (Scan->InstanceWidth - LeadingLineThickness
  438.                                     - TrailingLineThickness) - 2,Scan->WhereY + LeadingSpace
  439.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,
  440.                                     0,TextLineHeight);
  441.                                 DrawTextLine(Window,GetScreenFont(),FontPointSize,Scan->Name,
  442.                                     PtrSize(Scan->Name),Scan->WhereX + BoundingBoxThickness
  443.                                     + LeadingLineThickness - CurrentXIndex,Scan->WhereY + LeadingSpace
  444.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,ePlain);
  445.                             }
  446.                         if (Scan == CurrentlyHilited)
  447.                             {
  448.                                 DrawBoxFrame(Window,eWhite,Scan->WhereX + 1
  449.                                     + LeadingLineThickness - CurrentXIndex,Scan->WhereY + LeadingSpace
  450.                                     + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex + 1,
  451.                                     Scan->InstanceWidth - LeadingLineThickness
  452.                                     - TrailingLineThickness - 2,TextLineHeight + 1 - 2);
  453.                             }
  454.                         if (Scan->Type == eSymbolicLink)
  455.                             {
  456.                                 How = eMediumGrey;
  457.                             }
  458.                          else
  459.                             {
  460.                                 How = eBlack;
  461.                             }
  462.                         /* box */
  463.                         DrawBoxFrame(Window,How,Scan->WhereX
  464.                             + LeadingLineThickness - CurrentXIndex,Scan->WhereY + LeadingSpace
  465.                             + (Scan->Height - TextLineHeight) / 2 - CurrentYIndex,
  466.                             Scan->InstanceWidth - LeadingLineThickness
  467.                             - TrailingLineThickness,TextLineHeight + 1);
  468.                         /* leading line */
  469.                         DrawLine(Window,eBlack,Scan->WhereX - CurrentXIndex,Scan->WhereY
  470.                             + LeadingSpace + (Scan->Height) / 2 - CurrentYIndex,
  471.                             LeadingLineThickness,0);
  472.                         /* trailing line */
  473.                         if (Scan->Type != eFile)
  474.                             {
  475.                                 DrawLine(Window,eBlack,Scan->WhereX + Scan->InstanceWidth
  476.                                     - TrailingLineThickness - CurrentXIndex,Scan->WhereY + LeadingSpace
  477.                                     + (Scan->Height) / 2 - CurrentYIndex,TrailingLineThickness,0);
  478.                                 if (Scan->Type == eDirectory)
  479.                                     {
  480.                                         /* recursive indraw for directories */
  481.                                         if (Scan->Down == NIL)
  482.                                             {
  483.                                                 /* empty directory */
  484.                                                 DrawLine(Window,eBlack,Scan->WhereX + Scan->InstanceWidth
  485.                                                     - CurrentXIndex + 0,Scan->WhereY + LeadingSpace
  486.                                                     + (Scan->Height) / 2 - CurrentYIndex - 3,0,6);
  487.                                                 DrawLine(Window,eBlack,Scan->WhereX + Scan->InstanceWidth
  488.                                                     - CurrentXIndex + 3,Scan->WhereY + LeadingSpace
  489.                                                     + (Scan->Height) / 2 - CurrentYIndex - 2,0,4);
  490.                                                 DrawLine(Window,eBlack,Scan->WhereX + Scan->InstanceWidth
  491.                                                     - CurrentXIndex + 6,Scan->WhereY + LeadingSpace
  492.                                                     + (Scan->Height) / 2 - CurrentYIndex - 1,0,2);
  493.                                             }
  494.                                         else
  495.                                             {
  496.                                                 Node*                    SubScan;
  497.                                                 OrdType                Upper;
  498.                                                 OrdType                Lower;
  499.  
  500.                                                 RedrawArea(Scan->Down);
  501.                                                 /* this item was a non-empty directory.  Draw from the */
  502.                                                 /* midpoint of the first item to the midpoint of the */
  503.                                                 /* last item */
  504.                                                 SubScan = Scan->Down;
  505.                                                 Upper = SubScan->WhereY + LeadingSpace
  506.                                                     + (SubScan->Height) / 2 - CurrentYIndex;
  507.                                                 while (SubScan->Next != NIL)
  508.                                                     {
  509.                                                         SubScan = SubScan->Next;
  510.                                                     }
  511.                                                 Lower = SubScan->WhereY + LeadingSpace
  512.                                                     + (SubScan->Height) / 2 - CurrentYIndex;
  513.                                                 DrawLine(Window,eBlack,Scan->WhereX + Scan->InstanceWidth
  514.                                                     - CurrentXIndex,Upper,0,Lower - Upper);
  515.                                             }
  516.                                     }
  517.                             }
  518.                     }
  519.                 Scan = Scan->Next;
  520.             }
  521.     }
  522.  
  523.  
  524. /* clipping region must be properly set up before calling this */
  525. void                            RedrawAreaStart(MyBoolean DoAliases)
  526.     {
  527.         if (AliasesOnTop)
  528.             {
  529.                 RedrawArea(GlobalList);
  530.             }
  531.         if ((DoAliases || AliasesOnTop) && ShowAliasLines)
  532.             {
  533.                 AliasVec*                AliasScan;
  534.  
  535.                 AliasScan = ListOfAliases;
  536.                 while (AliasScan != NIL)
  537.                     {
  538.                         DrawLine(Window,AliasPattern,AliasScan->StartX - CurrentXIndex,
  539.                             AliasScan->StartY - CurrentYIndex + LeadingSpace,
  540.                             AliasScan->DisplaceX,AliasScan->DisplaceY);
  541.                         AliasScan = AliasScan->Next;
  542.                     }
  543.             }
  544.         if (!AliasesOnTop)
  545.             {
  546.                 RedrawArea(GlobalList);
  547.             }
  548.     }
  549.  
  550.  
  551. void                            DeselectAll(Node* List)
  552.     {
  553.         while (List != NIL)
  554.             {
  555.                 List->SelectedFlag = False;
  556.                 DeselectAll(List->Down);
  557.                 List = List->Next;
  558.             }
  559.         CurrentlyHilited = NIL;
  560.     }
  561.  
  562.  
  563. /* X and Y must be normalized to the tree's origin */
  564. MyBoolean                    MouseDownSelect(Node* List, OrdType X, OrdType Y)
  565.     {
  566.         while (List != NIL)
  567.             {
  568.                 if ((X >= List->WhereX) && (Y >= List->WhereY)
  569.                     && (X < List->WhereX + List->Width)
  570.                     && (Y < List->WhereY + List->Height))
  571.                     {
  572.                         OrdType            LocalX;
  573.                         OrdType            LocalY;
  574.                         OrdType            LocalWidth;
  575.                         OrdType            LocalHeight;
  576.  
  577.                         LocalX = List->WhereX + LeadingLineThickness;
  578.                         LocalY = List->WhereY + (List->Height - TextLineHeight) / 2;
  579.                         LocalWidth = List->InstanceWidth - LeadingLineThickness
  580.                             - TrailingLineThickness;
  581.                         LocalHeight = TextLineHeight + 1;
  582.                         if ((X >= LocalX) && (Y >= LocalY) && (X < LocalX + LocalWidth)
  583.                             && (Y < LocalY + LocalHeight))
  584.                             {
  585.                                 /* found it! */
  586.                                 List->SelectedFlag = !List->SelectedFlag;
  587.                                 if (List->SelectedFlag)
  588.                                     {
  589.                                         CurrentlyHilited = List;
  590.                                     }
  591.                                  else
  592.                                     {
  593.                                         CurrentlyHilited = NIL;
  594.                                     }
  595.                                 return True;
  596.                             }
  597.                          else
  598.                             {
  599.                                 if (MouseDownSelect(List->Down,X,Y))
  600.                                     {
  601.                                         return True;
  602.                                     }
  603.                             }
  604.                     }
  605.                 List = List->Next;
  606.             }
  607.         return False;
  608.     }
  609.  
  610.  
  611. void                            HScrollHook(long Parameter, ScrollType How, void* DontCare)
  612.     {
  613.         long                        Old;
  614.  
  615.         Old = CurrentXIndex;
  616.         switch (How)
  617.             {
  618.                 case eScrollToPosition:
  619.                     CurrentXIndex = Parameter;
  620.                     break;
  621.                 case eScrollPageMinus:
  622.                     CurrentXIndex -= (GetWindowWidth(Window) - 15) - ScrollIncrement;
  623.                     break;
  624.                 case eScrollPagePlus:
  625.                     CurrentXIndex += (GetWindowWidth(Window) - 15) - ScrollIncrement;
  626.                     break;
  627.                 case eScrollLineMinus:
  628.                     CurrentXIndex -= ScrollIncrement;
  629.                     break;
  630.                 case eScrollLinePlus:
  631.                     CurrentXIndex += ScrollIncrement;
  632.                     break;
  633.                 default:
  634.                     EXECUTE(PRERR(AllowResume,"HScrollHook:  Unknown scroll opcode"));
  635.                     break;
  636.             }
  637.         if (CurrentXIndex > TotalWidth - (GetWindowWidth(Window) - 15))
  638.             {
  639.                 CurrentXIndex = TotalWidth - (GetWindowWidth(Window) - 15);
  640.             }
  641.         if (CurrentXIndex < 0)
  642.             {
  643.                 CurrentXIndex = 0;
  644.             }
  645.         SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  646.             GetWindowHeight(Window) - LeadingSpace - 15);
  647.         ScrollArea(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  648.             GetWindowHeight(Window) - LeadingSpace - 15,Old - CurrentXIndex,0);
  649.         if (Old > CurrentXIndex)
  650.             {
  651.                 /* this means we opened a hole on the left edge */
  652.                 AddClipRect(Window,0,LeadingSpace,Old - CurrentXIndex,
  653.                     GetWindowHeight(Window) - LeadingSpace - 15);
  654.                 RedrawAreaStart(True);
  655.             }
  656.         else if (Old < CurrentXIndex)
  657.             {
  658.                 /* this means we opened a hole on the right edge */
  659.                 AddClipRect(Window,GetWindowWidth(Window) - 15 - (CurrentXIndex - Old),
  660.                     LeadingSpace,CurrentXIndex - Old,GetWindowHeight(Window) - LeadingSpace - 15);
  661.                 RedrawAreaStart(True);
  662.             }
  663.         /* else we didn't change so don't bother redrawing */
  664.         SetScrollIndex(HorizontalScroll,CurrentXIndex);
  665.         RedrawScrollBar(HorizontalScroll);
  666.     }
  667.  
  668.  
  669. void                            VScrollHook(long Parameter, ScrollType How, void* DontCare)
  670.     {
  671.         long                        Old;
  672.  
  673.         Old = CurrentYIndex;
  674.         switch (How)
  675.             {
  676.                 case eScrollToPosition:
  677.                     CurrentYIndex = Parameter;
  678.                     break;
  679.                 case eScrollPageMinus:
  680.                     CurrentYIndex -= (GetWindowHeight(Window) - 15)
  681.                         - LeadingSpace - ScrollIncrement;
  682.                     break;
  683.                 case eScrollPagePlus:
  684.                     CurrentYIndex += (GetWindowHeight(Window) - 15)
  685.                         - LeadingSpace - ScrollIncrement;
  686.                     break;
  687.                 case eScrollLineMinus:
  688.                     CurrentYIndex -= ScrollIncrement;
  689.                     break;
  690.                 case eScrollLinePlus:
  691.                     CurrentYIndex += ScrollIncrement;
  692.                     break;
  693.                 default:
  694.                     EXECUTE(PRERR(AllowResume,"VScrollHook:  Unknown scroll opcode"));
  695.                     break;
  696.             }
  697.         if (CurrentYIndex > TotalHeight - (GetWindowHeight(Window) - 15 - LeadingSpace))
  698.             {
  699.                 CurrentYIndex = TotalHeight - (GetWindowHeight(Window) - 15 - LeadingSpace);
  700.             }
  701.         if (CurrentYIndex < 0)
  702.             {
  703.                 CurrentYIndex = 0;
  704.             }
  705.         SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  706.             GetWindowHeight(Window) - LeadingSpace - 15);
  707.         ScrollArea(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  708.             GetWindowHeight(Window) - LeadingSpace - 15,0,Old - CurrentYIndex);
  709.         if (Old > CurrentYIndex)
  710.             {
  711.                 /* this means we opened a hole on the top edge */
  712.                 AddClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  713.                     Old - CurrentYIndex);
  714.                 RedrawAreaStart(True);
  715.             }
  716.         else if (Old < CurrentYIndex)
  717.             {
  718.                 /* this means we opened a hole on the bottom edge */
  719.                 AddClipRect(Window,0,GetWindowHeight(Window) - 15 - (CurrentYIndex - Old),
  720.                     GetWindowWidth(Window) - 15,CurrentYIndex - Old);
  721.                 RedrawAreaStart(True);
  722.             }
  723.         /* else we didn't change so don't bother redrawing */
  724.         SetScrollIndex(VerticalScroll,CurrentYIndex);
  725.         RedrawScrollBar(VerticalScroll);
  726.     }
  727.  
  728.  
  729. void                            UpdateProcedure(void* Refcon)
  730.     {
  731.         char*                        TotalNumber;
  732.  
  733.         SetClipRect(Window,0,0,GetWindowWidth(Window),GetWindowHeight(Window));
  734.         DrawLine(Window,eBlack,0,LeadingSpace - 1,GetWindowWidth(Window),0);
  735.         DrawBitmap(Window,GetWindowWidth(Window) - 15,GetWindowHeight(Window) - 15,
  736.             GetGrowIcon(True));
  737.         TotalNumber = IntegerToString(DirectoryCount + FileCount + SymbolicLinkCount);
  738.         if (TotalNumber != NIL)
  739.             {
  740.                 char*                        FileNumber;
  741.  
  742.                 FileNumber = IntegerToString(FileCount);
  743.                 if (FileNumber != NIL)
  744.                     {
  745.                         char*                    DirectoryNumber;
  746.  
  747.                         DirectoryNumber = IntegerToString(DirectoryCount);
  748.                         if (DirectoryNumber != NIL)
  749.                             {
  750.                                 char*                    LinkNumber;
  751.  
  752.                                 LinkNumber = IntegerToString(SymbolicLinkCount);
  753.                                 if (LinkNumber != NIL)
  754.                                     {
  755.                                         char*                    Str1;
  756.  
  757.                                         Str1 = StringFromRaw(
  758.                                             "_ Items:  _ Directories, _ Files, _ Links");
  759.                                         if (Str1 != NIL)
  760.                                             {
  761.                                                 char*                    Str2;
  762.  
  763.                                                 Str2 = StringToBlockCopy(Str1);
  764.                                                 if (Str2 != NIL)
  765.                                                     {
  766.                                                         char*                        Key;
  767.  
  768.                                                         Key = BlockFromRaw("_",1);
  769.                                                         if (Key != NIL)
  770.                                                             {
  771.                                                                 char*                        AfterFirst;
  772.  
  773.                                                                 AfterFirst = ReplaceBlockCopy(Str1,Key,TotalNumber);
  774.                                                                 if (AfterFirst != NIL)
  775.                                                                     {
  776.                                                                         char*                        AfterSecond;
  777.  
  778.                                                                         AfterSecond = ReplaceBlockCopy(AfterFirst,
  779.                                                                             Key,DirectoryNumber);
  780.                                                                         if (AfterSecond != NIL)
  781.                                                                             {
  782.                                                                                 char*                        AfterThird;
  783.  
  784.                                                                                 AfterThird = ReplaceBlockCopy(AfterSecond,
  785.                                                                                     Key,FileNumber);
  786.                                                                                 if (AfterThird != NIL)
  787.                                                                                     {
  788.                                                                                         char*                        AfterFourth;
  789.  
  790.                                                                                         AfterFourth = ReplaceBlockCopy(AfterThird,
  791.                                                                                             Key,LinkNumber);
  792.                                                                                         if (AfterFourth != NIL)
  793.                                                                                             {
  794.                                                                                                 DrawTextLine(Window,GetScreenFont(),
  795.                                                                                                     FontPointSize,AfterFourth,
  796.                                                                                                     PtrSize(AfterFourth),4,0,eBold);
  797.                                                                                                 ReleasePtr(AfterFourth);
  798.                                                                                             }
  799.                                                                                         ReleasePtr(AfterThird);
  800.                                                                                     }
  801.                                                                                 ReleasePtr(AfterSecond);
  802.                                                                             }
  803.                                                                         ReleasePtr(AfterFirst);
  804.                                                                     }
  805.                                                                 ReleasePtr(Key);
  806.                                                             }
  807.                                                         ReleasePtr(Str2);
  808.                                                     }
  809.                                                 ReleasePtr(Str1);
  810.                                             }
  811.                                         ReleasePtr(LinkNumber);
  812.                                     }
  813.                                 ReleasePtr(DirectoryNumber);
  814.                             }
  815.                         ReleasePtr(FileNumber);
  816.                     }
  817.                 ReleasePtr(TotalNumber);
  818.             }
  819.         RedrawScrollBar(HorizontalScroll);
  820.         RedrawScrollBar(VerticalScroll);
  821.         SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  822.             GetWindowHeight(Window) - LeadingSpace - 15);
  823.         RedrawAreaStart(True);
  824.     }
  825.  
  826.  
  827. void                            JumpSymbolicLink(void)
  828.     {
  829.         if (CurrentlyHilited != NIL)
  830.             {
  831.                 if (CurrentlyHilited->Type == eSymbolicLink)
  832.                     {
  833.                         OrdType                     StupidX;
  834.                         OrdType                        StupidY;
  835.                         Node*                            WhichOne;
  836.                         FileSpec*                    Target;
  837.  
  838.                         SetWatchCursor();
  839.                         Target = DereferenceSymbolicLink(CurrentlyHilited->Location);
  840.                         if (Target != NIL)
  841.                             {
  842.                                 WhichOne = FindMatchingItem(GlobalList,Target,&StupidX,&StupidY);
  843.                                 DisposeFileSpec(Target);
  844.                                 OtherOne = CurrentlyHilited;
  845.                                 DeselectAll(GlobalList);
  846.                                 CurrentlyHilited = WhichOne;
  847.                                 if (CurrentlyHilited != NIL)
  848.                                     {
  849.                                         CurrentlyHilited->SelectedFlag = True;
  850.                                     }
  851.                                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  852.                                     GetWindowHeight(Window) - 15 - LeadingSpace);
  853.                                 RedrawAreaStart(False);
  854.                                 ShowSpecifiedItem(CurrentlyHilited);
  855.                             }
  856.                     }
  857.             }
  858.     }
  859.  
  860.  
  861. void                            ReturnToPreviousLink(void)
  862.     {
  863.         if (OtherOne != NIL)
  864.             {
  865.                 Node*                    Swapper;
  866.  
  867.                 Swapper = CurrentlyHilited;
  868.                 DeselectAll(GlobalList);
  869.                 CurrentlyHilited = OtherOne;
  870.                 OtherOne = Swapper;
  871.                 CurrentlyHilited->SelectedFlag = True;
  872.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  873.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  874.                 RedrawAreaStart(False);
  875.                 ShowSpecifiedItem(CurrentlyHilited);
  876.             }
  877.     }
  878.  
  879.  
  880. static void                HiliteRecursive(Node* List, FileSpec* DesiredTarget)
  881.     {
  882.         while (List != NIL)
  883.             {
  884.                 if (List->Type == eSymbolicLink)
  885.                     {
  886.                         FileSpec*            Temp;
  887.  
  888.                         Temp = DereferenceSymbolicLink(List->Location);
  889.                         if (Temp != NIL)
  890.                             {
  891.                                 if (CompareFileSpecs(Temp,DesiredTarget))
  892.                                     {
  893.                                         if (CurrentlyHilited == NIL)
  894.                                             {
  895.                                                 /* remember the first one */
  896.                                                 CurrentlyHilited = List;
  897.                                             }
  898.                                         List->SelectedFlag = True;
  899.                                     }
  900.                                 DisposeFileSpec(Temp);
  901.                             }
  902.                     }
  903.                 HiliteRecursive(List->Down,DesiredTarget);
  904.                 List = List->Next;
  905.             }
  906.     }
  907.  
  908.  
  909. void                            HiliteLinksToCurrent(void)
  910.     {
  911.         Node*                        CurrentBackupCopy;
  912.  
  913.         if (CurrentlyHilited != NIL)
  914.             {
  915.                 FileSpec*                Original;
  916.  
  917.                 SetWatchCursor();
  918.                 CurrentBackupCopy = CurrentlyHilited;
  919.                 Original = CurrentlyHilited->Location;
  920.                 OtherOne = CurrentlyHilited;
  921.                 DeselectAll(GlobalList);
  922.                 HiliteRecursive(GlobalList,Original);
  923.                 if (CurrentlyHilited == NIL)
  924.                     {
  925.                         ErrorBeep();
  926.                         CurrentlyHilited = CurrentBackupCopy;
  927.                         CurrentlyHilited->SelectedFlag = True;
  928.                     }
  929.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  930.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  931.                 RedrawAreaStart(False);
  932.                 ShowSpecifiedItem(CurrentlyHilited);
  933.             }
  934.     }
  935.  
  936.  
  937. void                            ShowSpecifiedItem(Node* Item)
  938.     {
  939.         if (Item != NIL)
  940.             {
  941.                 if ((Item->WhereX < CurrentXIndex + 15)
  942.                     || (Item->WhereX + Item->InstanceWidth
  943.                     > CurrentXIndex + GetWindowWidth(Window) - 15 - 15))
  944.                     {
  945.                         HScrollHook(Item->WhereX
  946.                             - (GetWindowWidth(Window) - 15 - Item->InstanceWidth) / 2,
  947.                             eScrollToPosition,NIL);
  948.                     }
  949.                 if ((Item->WhereY + (Item->Height - TextLineHeight) / 2
  950.                     < CurrentYIndex + 15)
  951.                     || (Item->WhereY + (Item->Height - TextLineHeight) / 2 + TextLineHeight
  952.                     > CurrentYIndex + GetWindowHeight(Window) - 15 - 15 - LeadingSpace))
  953.                     {
  954.                         VScrollHook(Item->WhereY + (Item->Height - TextLineHeight) / 2
  955.                             -    (GetWindowHeight(Window) - 15 - LeadingSpace) / 2,eScrollToPosition,NIL);
  956.                     }
  957.             }
  958.     }
  959.  
  960.  
  961. typedef enum {eLookForCurrent, eLookForNext, eLookForLast} SearchStateType;
  962.  
  963. /* while FlippedOver is false, the procedure scans for CurrentlyHilited and */
  964. /* then sets it True.  Then it stops at the next selected item */
  965. static void                SelectSearch(Node* List, Node** BeforeCurrent,
  966.                                         Node** AfterCurrent, Node** Last, SearchStateType* State)
  967.     {
  968.         while (List != NIL)
  969.             {
  970.                 SelectSearch(List->Down,BeforeCurrent,AfterCurrent,Last,State);
  971.                 if (List->SelectedFlag)
  972.                     {
  973.                         switch (*State)
  974.                             {
  975.                                 case eLookForCurrent:
  976.                                     if (List == CurrentlyHilited)
  977.                                         {
  978.                                             /* found current! */
  979.                                             *State = eLookForNext;
  980.                                         }
  981.                                      else
  982.                                         {
  983.                                             *BeforeCurrent = List;
  984.                                         }
  985.                                     break;
  986.                                 case eLookForNext:
  987.                                     *AfterCurrent = List;
  988.                                     *State = eLookForLast;
  989.                                     break;
  990.                                 case eLookForLast:
  991.                                     *Last = List;
  992.                                     break;
  993.                             }
  994.                     }
  995.                 List = List->Next;
  996.             }
  997.     }
  998.  
  999.  
  1000. void                            AdvanceToNext(void)
  1001.     {
  1002.         if (CurrentlyHilited != NIL)
  1003.             {
  1004.                 SearchStateType        State;
  1005.                 Node*                            BeforeCurrent;
  1006.                 Node*                            AfterCurrent;
  1007.                 Node*                            Last;
  1008.  
  1009.                 State = eLookForCurrent;
  1010.                 BeforeCurrent = NIL;
  1011.                 AfterCurrent = NIL;
  1012.                 Last = NIL;
  1013.                 SelectSearch(GlobalList,&BeforeCurrent,&AfterCurrent,&Last,&State);
  1014.                 if (BeforeCurrent == NIL)
  1015.                     {
  1016.                         BeforeCurrent = CurrentlyHilited;
  1017.                     }
  1018.                 if (AfterCurrent == NIL)
  1019.                     {
  1020.                         AfterCurrent = CurrentlyHilited;
  1021.                     }
  1022.                 if (Last == NIL)
  1023.                     {
  1024.                         Last = AfterCurrent;
  1025.                     }
  1026.                 CurrentlyHilited = AfterCurrent;
  1027.                 CheckPtrExistence((char*)CurrentlyHilited); /* it had better not be NIL! */
  1028.                 CurrentlyHilited->SelectedFlag = True;
  1029.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1030.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  1031.                 RedrawAreaStart(False);
  1032.                 ShowSpecifiedItem(CurrentlyHilited);
  1033.             }
  1034.     }
  1035.  
  1036.  
  1037. void                            AdvanceToPrevious(void)
  1038.     {
  1039.         if (CurrentlyHilited != NIL)
  1040.             {
  1041.                 SearchStateType        State;
  1042.                 Node*                            BeforeCurrent;
  1043.                 Node*                            AfterCurrent;
  1044.                 Node*                            Last;
  1045.  
  1046.                 State = eLookForCurrent;
  1047.                 BeforeCurrent = NIL;
  1048.                 AfterCurrent = NIL;
  1049.                 Last = NIL;
  1050.                 SelectSearch(GlobalList,&BeforeCurrent,&AfterCurrent,&Last,&State);
  1051.                 if (BeforeCurrent == NIL)
  1052.                     {
  1053.                         BeforeCurrent = CurrentlyHilited;
  1054.                     }
  1055.                 if (AfterCurrent == NIL)
  1056.                     {
  1057.                         AfterCurrent = CurrentlyHilited;
  1058.                     }
  1059.                 if (Last == NIL)
  1060.                     {
  1061.                         Last = AfterCurrent;
  1062.                     }
  1063.                 CurrentlyHilited = BeforeCurrent;
  1064.                 CheckPtrExistence((char*)CurrentlyHilited); /* it had better not be NIL! */
  1065.                 CurrentlyHilited->SelectedFlag = True;
  1066.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1067.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  1068.                 RedrawAreaStart(False);
  1069.                 ShowSpecifiedItem(CurrentlyHilited);
  1070.             }
  1071.     }
  1072.  
  1073.  
  1074. void                            EnterSubLevel(void)
  1075.     {
  1076.         if (CurrentlyHilited != NIL)
  1077.             {
  1078.                 /* enter nearest contained level */
  1079.                 if (CurrentlyHilited->Down != NIL)
  1080.                     {
  1081.                         OrdType                    Index;
  1082.                         Node*                        Scan;
  1083.  
  1084.                         Scan = CurrentlyHilited->Down;
  1085.                         Index = 0;
  1086.                         while ((Scan->Next != NIL) && (CurrentlyHilited->Height / 2
  1087.                             >= Index + Scan->Height))
  1088.                             {
  1089.                                 Index += Scan->Height;
  1090.                                 Scan = Scan->Next;
  1091.                             }
  1092.                         DeselectAll(GlobalList);
  1093.                         Scan->SelectedFlag = True;
  1094.                         CurrentlyHilited = Scan;
  1095.                         SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1096.                             GetWindowHeight(Window) - 15 - LeadingSpace);
  1097.                     }
  1098.                 RedrawAreaStart(False);
  1099.                 ShowSpecifiedItem(CurrentlyHilited);
  1100.             }
  1101.     }
  1102.  
  1103.  
  1104. static MyBoolean        ExitCurrentLevel(Node* List)
  1105.     {
  1106.         Node*                            Scan;
  1107.  
  1108.         Scan = List;
  1109.         while (Scan != NIL)
  1110.             {
  1111.                 if (ExitCurrentLevel(Scan->Down))
  1112.                     {
  1113.                         if (CurrentlyHilited == NIL)
  1114.                             {
  1115.                                 CurrentlyHilited = Scan;
  1116.                             }
  1117.                         return True;
  1118.                     }
  1119.                 if (Scan == CurrentlyHilited)
  1120.                     {
  1121.                         CurrentlyHilited = NIL;
  1122.                         return True;
  1123.                     }
  1124.                 Scan = Scan->Next;
  1125.             }
  1126.         return False;
  1127.     }
  1128.  
  1129.  
  1130. void                            ExitLevel(void)
  1131.     {
  1132.         if (CurrentlyHilited != NIL)
  1133.             {
  1134.                 Node*                        Temp;
  1135.                 Node*                        Old;
  1136.  
  1137.                 Old = CurrentlyHilited;
  1138.                 ExitCurrentLevel(GlobalList);
  1139.                 Temp = CurrentlyHilited;
  1140.                 if (Temp == NIL)
  1141.                     {
  1142.                         Temp = Old;
  1143.                     }
  1144.                 DeselectAll(GlobalList);
  1145.                 Temp->SelectedFlag = True;
  1146.                 CurrentlyHilited = Temp;
  1147.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1148.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  1149.                 RedrawAreaStart(False);
  1150.                 ShowSpecifiedItem(Temp);
  1151.             }
  1152.     }
  1153.  
  1154.  
  1155. void                            GoDown(MyBoolean JumpToBottom)
  1156.     {
  1157.         if (CurrentlyHilited != NIL)
  1158.             {
  1159.                 Node*                    Scan;
  1160.  
  1161.                 Scan = CurrentlyHilited;
  1162.              Loopish:
  1163.                 if (Scan->Next != NIL)
  1164.                     {
  1165.                         Scan = Scan->Next;
  1166.                         if (JumpToBottom)
  1167.                             {
  1168.                                 goto Loopish;
  1169.                             }
  1170.                     }
  1171.                 DeselectAll(GlobalList);
  1172.                 Scan->SelectedFlag = True;
  1173.                 CurrentlyHilited = Scan;
  1174.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1175.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  1176.                 RedrawAreaStart(False);
  1177.                 ShowSpecifiedItem(Scan);
  1178.             }
  1179.     }
  1180.  
  1181.  
  1182. void                            GoUp(MyBoolean JumpToTop)
  1183.     {
  1184.         if (CurrentlyHilited != NIL)
  1185.             {
  1186.                 Node*                    Old;
  1187.  
  1188.                 Old = CurrentlyHilited;
  1189.                 if (ExitCurrentLevel(GlobalList))
  1190.                     {
  1191.                         Node*                    Temp;
  1192.  
  1193.                         ERROR(CurrentlyHilited->Down == NIL,
  1194.                             PRERR(ForceAbort,"GoUp:  Internal error:  list is inconsistent"));
  1195.                         Temp = CurrentlyHilited->Down;
  1196.                         if (!JumpToTop)
  1197.                             {
  1198.                                 while ((Temp != Old) && Temp->Next != Old)
  1199.                                     {
  1200.                                         Temp = Temp->Next;
  1201.                                         ERROR(Temp==NIL,PRERR(ForceAbort,"GoUp: Internal Error list is inconsistent"));
  1202.                                     }
  1203.                             }
  1204.                         DeselectAll(GlobalList);
  1205.                         Temp->SelectedFlag = True;
  1206.                         CurrentlyHilited = Temp;
  1207.                     }
  1208.                 SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1209.                     GetWindowHeight(Window) - 15 - LeadingSpace);
  1210.                 RedrawAreaStart(False);
  1211.                 ShowSpecifiedItem(CurrentlyHilited);
  1212.             }
  1213.     }
  1214.  
  1215.  
  1216. /* performs case insensitive comparison to see if Instance is contained in Search */
  1217. /* this could be improved to use wildcards. */
  1218. static MyBoolean        TextPtrsAreEqual(char* Instance, char* Search)
  1219.     {
  1220.         long                        InstanceLength;
  1221.         long                        SearchLength;
  1222.         long                        Scan;
  1223.  
  1224.         InstanceLength = PtrSize(Instance);
  1225.         SearchLength = PtrSize(Search);
  1226.         for (Scan = 0; Scan <= SearchLength - InstanceLength; Scan += 1)
  1227.             {
  1228.                 long                        Index;
  1229.  
  1230.                 for (Index = 0; Index < InstanceLength; Index += 1)
  1231.                     {
  1232.                         char                        Left;
  1233.                         char                        Right;
  1234.  
  1235.                         Left = Instance[Index];
  1236.                         if ((Left >= 'A') && (Left <= 'Z'))
  1237.                             {
  1238.                                 Left = Left - 'A' + 'a';
  1239.                             }
  1240.                         Right = Search[Scan + Index];
  1241.                         if ((Right >= 'A') && (Right <= 'Z'))
  1242.                             {
  1243.                                 Right = Right - 'A' + 'a';
  1244.                             }
  1245.                         if (Left != Right)
  1246.                             {
  1247.                                 goto SkipToNextPoint;
  1248.                             }
  1249.                     }
  1250.                 return True; /* we get here if Instance was entirely in Search */
  1251.              SkipToNextPoint:
  1252.                 ;
  1253.             }
  1254.         return False;
  1255.     }
  1256.  
  1257.  
  1258. typedef enum {eFindLookForCurrent, eFindLookForNext, eFindStop} FindStateType;
  1259.  
  1260. static void                RecursiveFind(Node* List, Node** Found, FindStateType* State)
  1261.     {
  1262.         while (List != NIL)
  1263.             {
  1264.                 switch (*State)
  1265.                     {
  1266.                         case eFindLookForCurrent:
  1267.                             if (List == CurrentlyHilited)
  1268.                                 {
  1269.                                     /* found current! */
  1270.                                     *State = eLookForNext;
  1271.                                 }
  1272.                             break;
  1273.                         case eFindLookForNext:
  1274.                             if (TextPtrsAreEqual(SearchKey,List->Name))
  1275.                                 {
  1276.                                     *Found = List;
  1277.                                     *State = eFindStop;
  1278.                                 }
  1279.                             break;
  1280.                         case eFindStop:
  1281.                             return;
  1282.                             break;
  1283.                     }
  1284.                 RecursiveFind(List->Down,Found,State);
  1285.                 List = List->Next;
  1286.             }
  1287.     }
  1288.  
  1289.  
  1290. void                            Find(void)
  1291.     {
  1292.         Node*                        Found;
  1293.         FindStateType        State;
  1294.  
  1295.         Found = NIL;
  1296.         if (CurrentlyHilited == NIL)
  1297.             {
  1298.                 State = eFindLookForNext;
  1299.             }
  1300.          else
  1301.             {
  1302.                 State = eFindLookForCurrent;
  1303.             }
  1304.         RecursiveFind(GlobalList,&Found,&State);
  1305.         DeselectAll(GlobalList);
  1306.         if (Found == NIL)
  1307.             {
  1308.                 ErrorBeep();
  1309.             }
  1310.          else
  1311.             {
  1312.                 CurrentlyHilited = Found;
  1313.                 CurrentlyHilited->SelectedFlag = True;
  1314.             }
  1315.         OtherOne = NIL;
  1316.         SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1317.             GetWindowHeight(Window) - 15 - LeadingSpace);
  1318.         RedrawAreaStart(False);
  1319.         ShowSpecifiedItem(CurrentlyHilited);
  1320.     }
  1321.  
  1322.  
  1323. void                            ShowFileInfoForSelection(Node* Item)
  1324.     {
  1325.         FileInfoRec            Info;
  1326.  
  1327.         CheckPtrExistence(Item);
  1328.         if (Item->Location != NIL)
  1329.             {
  1330.                 if (GetFileStatistics(Item->Location,&Info))
  1331.                     {
  1332.                     }
  1333.             }
  1334.     }
  1335.  
  1336.  
  1337. int                                main(int argc, char* argv[])
  1338.     {
  1339.         MyBoolean                GotTheDirectory;
  1340.         MyBoolean                ContinueFlag;
  1341.         FileSpec*                RootDirectory;
  1342.  
  1343.         APRINT(("+main"));
  1344.  
  1345.         /* level 0 initialization */
  1346.         if (!InitializeScreen())
  1347.             {
  1348.                 goto TotalFailureEscapePoint;
  1349.             }
  1350.  
  1351.         /* level 1 initialization */
  1352.         InitializeAlertSubsystem();
  1353.         InitializeGrowIcon();
  1354.  
  1355.         /* application initialization */
  1356.         mmAppleMenu = MakeAppleMenu();
  1357.         mAboutProgram = MakeNewMenuItem(mmAppleMenu,"About DirTree...",0);
  1358.         ShowMenu(mmAppleMenu);
  1359.         mmFileMenu = MakeNewMenu("File");
  1360.         mShowAliasLines = MakeNewMenuItem(mmFileMenu,"Show Alias Paths",0);
  1361.         mShowAliasesOnTop = MakeNewMenuItem(mmFileMenu,"Alias Paths Above Text",0);
  1362.         AppendSeparator(mmFileMenu);
  1363.         mClose = MakeNewMenuItem(mmFileMenu,"Close",'W');
  1364.         AppendSeparator(mmFileMenu);
  1365.         mQuit = MakeNewMenuItem(mmFileMenu,"Quit",'Q');
  1366.         ShowMenu(mmFileMenu);
  1367.         mmEditMenu = MakeNewMenu("Edit");
  1368.         mUndo = MakeNewMenuItem(mmEditMenu,"Undo",'Z');
  1369.         AppendSeparator(mmEditMenu);
  1370.         mCut = MakeNewMenuItem(mmEditMenu,"Cut",'X');
  1371.         mCopy = MakeNewMenuItem(mmEditMenu,"Copy",'C');
  1372.         mPaste = MakeNewMenuItem(mmEditMenu,"Paste",'V');
  1373.         mClear = MakeNewMenuItem(mmEditMenu,"Clear",0);
  1374.         mSelectAll = MakeNewMenuItem(mmEditMenu,"Select All",0);
  1375.         AppendSeparator(mmEditMenu);
  1376.         mJumpSymbolicLink = MakeNewMenuItem(mmEditMenu,"Jump To Link Target",'J');
  1377.         mReturnToPrevious = MakeNewMenuItem(mmEditMenu,"Return To Previous Item",'R');
  1378.         mWhoLinksToThisOne = MakeNewMenuItem(mmEditMenu,"Who Links To This File",'A');
  1379.         AppendSeparator(mmEditMenu);
  1380.         mShowCurrentItem = MakeNewMenuItem(mmEditMenu,"Show Current Selection",'S');
  1381.         mGetFileInfo = MakeNewMenuItem(mmEditMenu,"Get Info...",'I');
  1382.         AppendSeparator(mmEditMenu);
  1383.         mFind = MakeNewMenuItem(mmEditMenu,"Find...",'F');
  1384.         mFindAgain = MakeNewMenuItem(mmEditMenu,"Find Again",'G');
  1385.         ShowMenu(mmEditMenu);
  1386.  
  1387.         /* find out which directory to start with. */
  1388.         PrepareStartupDocuments(argc,argv);
  1389.         GotTheDirectory = False;
  1390.         SearchKey = AllocPtrCanFail(0,"SearchKey");
  1391.         do
  1392.             {
  1393.                 /* dummy event loop to let Macintosh receive open events */
  1394.                 GetAnEvent(NIL,NIL,NIL,NIL,NIL,NIL);
  1395.                 /* see if anything came in */
  1396.                 if (GetStartupObject(&RootDirectory))
  1397.                     {
  1398.                         GotTheDirectory = True;
  1399.                         /* if RootDirectory is NIL, then we do the entire file system, */
  1400.                         /* otherwise we do the directory that it contains */
  1401.                     }
  1402.             } while (!GotTheDirectory);
  1403.  
  1404.         /* create the graphics window */
  1405.         Window = MakeNewWindow(eDocumentWindow,eWindowClosable,eWindowZoomable,
  1406.             eWindowResizable,
  1407.             XLEAD + WindowOtherEdgeWidths(eDocumentWindow),
  1408.             1 + WindowTitleBarHeight(eDocumentWindow),
  1409.             GetScreenWidth() - (XLEAD + WindowOtherEdgeWidths(eDocumentWindow)) - 1 - 2,
  1410.             GetScreenHeight() - (1 + WindowTitleBarHeight(eDocumentWindow)) - 1 - 2,
  1411.             &UpdateProcedure,NIL);
  1412.         if (Window == 0)
  1413.             {
  1414.              Oops:
  1415.                 AlertHalt("Error:  Couldn't open window.",NIL);
  1416.                 return 0;
  1417.             }
  1418.         TextLineHeight = GetFontHeight(GetScreenFont(),FontPointSize);
  1419.         LeadingSpace = TextLineHeight * NumStatusLines + 2;
  1420.         VerticalScroll = NewScrollBar(Window,eVScrollBar,GetWindowWidth(Window) - 15,
  1421.             LeadingSpace -1,GetWindowHeight(Window) + 2 - LeadingSpace - 15);
  1422.         if (VerticalScroll == NIL)
  1423.             {
  1424.                 goto Oops;
  1425.             }
  1426.         HorizontalScroll = NewScrollBar(Window,eHScrollBar,-1,GetWindowHeight(Window) - 15,
  1427.             GetWindowWidth(Window) + 2 - 15);
  1428.         if (HorizontalScroll == NIL)
  1429.             {
  1430.                 goto Oops;
  1431.             }
  1432.  
  1433.         /* digest the file system */
  1434.         GlobalList = ListFromDirectoryStart(RootDirectory);
  1435.         if (RootDirectory != NIL)
  1436.             {
  1437.                 DisposeFileSpec(RootDirectory);
  1438.             }
  1439.         /* at least one item in GlobalList -- the root directory */
  1440.         if (ErrorOccurredFlag)
  1441.             {
  1442.                 AlertHalt("The program ran out of memory while analyzing "
  1443.                     "the specified directory.",NIL);
  1444.                 goto AwwSkipit;
  1445.             }
  1446.         FillInSizeFields(GlobalList,5,5,&TotalWidth,&TotalHeight);
  1447.         TotalWidth += 5;
  1448.         TotalHeight += 5;
  1449.         ListOfAliases = NIL;
  1450.         ResolveAliases(GlobalList);
  1451.         CurrentXIndex = 0;
  1452.         CurrentYIndex = (TotalHeight - (GetWindowHeight(Window) - LeadingSpace - 15)) / 2;
  1453.         SetMaxScrollIndex(VerticalScroll,TotalHeight - (GetWindowHeight(Window)
  1454.             - LeadingSpace - 15) + 1);
  1455.         SetScrollIndex(VerticalScroll,CurrentYIndex);
  1456.         SetMaxScrollIndex(HorizontalScroll,TotalWidth - (GetWindowWidth(Window) - 15) + 1);
  1457.         SetScrollIndex(HorizontalScroll,CurrentXIndex);
  1458.  
  1459.         /* perform main event loop */
  1460.         ContinueFlag = True;
  1461.         while (ContinueFlag)
  1462.             {
  1463.                 OrdType                    XLoc;
  1464.                 OrdType                    YLoc;
  1465.                 ModifierFlags        Modifiers;
  1466.                 EventType                TheEvent;
  1467.                 char                        KeyPress;
  1468.                 MenuItemType*        MenuItem;
  1469.                 WinType*                EWin;
  1470.  
  1471.                 TheEvent = GetAnEvent(&XLoc,&YLoc,&Modifiers,&EWin,&MenuItem,&KeyPress);
  1472.                 switch (TheEvent)
  1473.                     {
  1474.                         case eNoEvent:
  1475.                             break;
  1476.                         case eKeyPressed:
  1477.                             if (KeyPress == 9)
  1478.                                 {
  1479.                                     if ((Modifiers & eCommandKey) == 0)
  1480.                                         {
  1481.                                             AdvanceToNext();
  1482.                                         }
  1483.                                      else
  1484.                                         {
  1485.                                             AdvanceToPrevious();
  1486.                                         }
  1487.                                 }
  1488.                             else if ((Modifiers & eControlKey) != 0)
  1489.                                 {
  1490.                                     if (KeyPress == eLeftArrow)
  1491.                                         {
  1492.                                             if ((Modifiers & eCommandKey) != 0)
  1493.                                                 {
  1494.                                                     HScrollHook(0,eScrollToPosition,NIL);
  1495.                                                 }
  1496.                                             else if ((Modifiers & eOptionKey) != 0)
  1497.                                                 {
  1498.                                                     HScrollHook(0,eScrollPageMinus,NIL);
  1499.                                                 }
  1500.                                             else
  1501.                                                 {
  1502.                                                     HScrollHook(0,eScrollLineMinus,NIL);
  1503.                                                 }
  1504.                                             RedrawScrollBar(HorizontalScroll);
  1505.                                         }
  1506.                                     else if (KeyPress == eRightArrow)
  1507.                                         {
  1508.                                             if ((Modifiers & eCommandKey) != 0)
  1509.                                                 {
  1510.                                                     HScrollHook(TotalWidth,eScrollToPosition,NIL);
  1511.                                                 }
  1512.                                             else if ((Modifiers & eOptionKey) != 0)
  1513.                                                 {
  1514.                                                     HScrollHook(0,eScrollPagePlus,NIL);
  1515.                                                 }
  1516.                                             else
  1517.                                                 {
  1518.                                                     HScrollHook(0,eScrollLinePlus,NIL);
  1519.                                                 }
  1520.                                             RedrawScrollBar(HorizontalScroll);
  1521.                                         }
  1522.                                     else if (KeyPress == eUpArrow)
  1523.                                         {
  1524.                                             if ((Modifiers & eCommandKey) != 0)
  1525.                                                 {
  1526.                                                     VScrollHook(0,eScrollToPosition,NIL);
  1527.                                                 }
  1528.                                             else if ((Modifiers & eOptionKey) != 0)
  1529.                                                 {
  1530.                                                     VScrollHook(0,eScrollPageMinus,NIL);
  1531.                                                 }
  1532.                                             else
  1533.                                                 {
  1534.                                                     VScrollHook(0,eScrollLineMinus,NIL);
  1535.                                                 }
  1536.                                             RedrawScrollBar(VerticalScroll);
  1537.                                         }
  1538.                                     else if (KeyPress == eDownArrow)
  1539.                                         {
  1540.                                             if ((Modifiers & eCommandKey) != 0)
  1541.                                                 {
  1542.                                                     VScrollHook(TotalHeight,eScrollToPosition,NIL);
  1543.                                                 }
  1544.                                             else if ((Modifiers & eOptionKey) != 0)
  1545.                                                 {
  1546.                                                     VScrollHook(0,eScrollPagePlus,NIL);
  1547.                                                 }
  1548.                                             else
  1549.                                                 {
  1550.                                                     VScrollHook(0,eScrollLinePlus,NIL);
  1551.                                                 }
  1552.                                             RedrawScrollBar(VerticalScroll);
  1553.                                         }
  1554.                                 }
  1555.                             else
  1556.                                 {
  1557.                                     if (KeyPress == eLeftArrow)
  1558.                                         {
  1559.                                             ExitLevel();
  1560.                                         }
  1561.                                     else if (KeyPress == eRightArrow)
  1562.                                         {
  1563.                                             EnterSubLevel();
  1564.                                         }
  1565.                                     else if (KeyPress == eUpArrow)
  1566.                                         {
  1567.                                             GoUp((Modifiers & eCommandKey) != 0);
  1568.                                         }
  1569.                                     else if (KeyPress == eDownArrow)
  1570.                                         {
  1571.                                             GoDown((Modifiers & eCommandKey) != 0);
  1572.                                         }
  1573.                                 }
  1574.                             break;
  1575.                         case eMouseDown:
  1576.                             if (ScrollHitTest(HorizontalScroll,XLoc,YLoc))
  1577.                                 {
  1578.                                     ScrollHitProc(HorizontalScroll,Modifiers,XLoc,YLoc,NIL,&HScrollHook);
  1579.                                 }
  1580.                             else if (ScrollHitTest(VerticalScroll,XLoc,YLoc))
  1581.                                 {
  1582.                                     ScrollHitProc(VerticalScroll,Modifiers,XLoc,YLoc,NIL,&VScrollHook);
  1583.                                 }
  1584.                             else if ((XLoc >= GetWindowWidth(Window) - 15)
  1585.                                 && (YLoc >= GetWindowHeight(Window) - 15)
  1586.                                 && (XLoc < GetWindowWidth(Window)) && (YLoc < GetWindowHeight(Window)))
  1587.                                 {
  1588.                                     UserGrowWindow(Window,XLoc,YLoc);
  1589.                                     goto WindowSizeChangedPoint;
  1590.                                 }
  1591.                             else if (XLoc >= LeadingSpace)
  1592.                                 {
  1593.                                     long double            TimerValue;
  1594.  
  1595.                                     TimerValue = ReadTimer();
  1596.                                     OtherOne = CurrentlyHilited;
  1597.                                     DeselectAll(GlobalList);
  1598.                                     MouseDownSelect(GlobalList,XLoc + CurrentXIndex,
  1599.                                         YLoc + CurrentYIndex - LeadingSpace);
  1600.                                     SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1601.                                         GetWindowHeight(Window) - 15 - LeadingSpace);
  1602.                                     RedrawAreaStart(False);
  1603.                                     if ((TimerDifference(TimerValue,LastClickTime)
  1604.                                         <= GetDoubleClickInterval())
  1605.                                         && (XLoc - LastClickX <= 3) && (XLoc - LastClickX >= -3)
  1606.                                         && (YLoc - LastClickY <= 3) && (YLoc - LastClickY >= -3))
  1607.                                         {
  1608.                                             if (CurrentlyHilited != NIL)
  1609.                                                 {
  1610.                                                     if (CurrentlyHilited->Type == eSymbolicLink)
  1611.                                                         {
  1612.                                                             JumpSymbolicLink();
  1613.                                                         }
  1614.                                                      else
  1615.                                                         {
  1616.                                                             HiliteLinksToCurrent();
  1617.                                                         }
  1618.                                                 }
  1619.                                             LastClickX = -32767;
  1620.                                             LastClickY = -32767;
  1621.                                         }
  1622.                                      else
  1623.                                         {
  1624.                                             LastClickTime = ReadTimer();
  1625.                                             LastClickX = XLoc;
  1626.                                             LastClickY = YLoc;
  1627.                                         }
  1628.                                 }
  1629.                             break;
  1630.                         case eMouseUp:
  1631.                             break;
  1632.                         case eCheckCursor:
  1633.                             SetArrowCursor();
  1634.                             break;
  1635.                         case eMenuStarting:
  1636.                             EnableMenuItem(mAboutProgram);
  1637.                             EnableMenuItem(mQuit);
  1638.                             EnableMenuItem(mClose);
  1639.                             EnableMenuItem(mShowAliasesOnTop);
  1640.                             if (AliasesOnTop)
  1641.                                 {
  1642.                                     SetItemCheckmark(mShowAliasesOnTop);
  1643.                                 }
  1644.                             EnableMenuItem(mShowAliasLines);
  1645.                             if (ShowAliasLines)
  1646.                                 {
  1647.                                     SetItemCheckmark(mShowAliasLines);
  1648.                                 }
  1649.                             if (CurrentlyHilited != NIL)
  1650.                                 {
  1651.                                     if (CurrentlyHilited->Type == eSymbolicLink)
  1652.                                         {
  1653.                                             EnableMenuItem(mJumpSymbolicLink);
  1654.                                         }
  1655.                                     EnableMenuItem(mWhoLinksToThisOne);
  1656.                                     EnableMenuItem(mShowCurrentItem);
  1657.                                     EnableMenuItem(mGetFileInfo);
  1658.                                 }
  1659.                             if (OtherOne != NIL)
  1660.                                 {
  1661.                                     EnableMenuItem(mReturnToPrevious);
  1662.                                 }
  1663.                             EnableMenuItem(mFind);
  1664.                             EnableMenuItem(mFindAgain);
  1665.                             break;
  1666.                         case eMenuCommand:
  1667.                             if (MenuItem == mAboutProgram)
  1668.                                 {
  1669.                                     AlertInfo("DirTree directory displayer by Thomas R. Lawrence "
  1670.                                         "(tomlaw@world.std.com), 1993.",NIL);
  1671.                                 }
  1672.                             else if ((MenuItem == mQuit) || (MenuItem == mClose))
  1673.                                 {
  1674.                                     ContinueFlag = False;
  1675.                                 }
  1676.                             else if (MenuItem == mShowAliasesOnTop)
  1677.                                 {
  1678.                                     AliasesOnTop = !AliasesOnTop;
  1679.                                     SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1680.                                         GetWindowHeight(Window) - 15 - LeadingSpace);
  1681.                                     RedrawAreaStart(True);
  1682.                                 }
  1683.                             else if (MenuItem == mShowAliasLines)
  1684.                                 {
  1685.                                     ShowAliasLines = !ShowAliasLines;
  1686.                                     SetClipRect(Window,0,LeadingSpace,GetWindowWidth(Window) - 15,
  1687.                                         GetWindowHeight(Window) - 15 - LeadingSpace);
  1688.                                     DrawBoxErase(Window,0,0,GetWindowWidth(Window),
  1689.                                         GetWindowHeight(Window));
  1690.                                     RedrawAreaStart(True);
  1691.                                 }
  1692.                             else if (MenuItem == mJumpSymbolicLink)
  1693.                                 {
  1694.                                     JumpSymbolicLink();
  1695.                                 }
  1696.                             else if (MenuItem == mReturnToPrevious)
  1697.                                 {
  1698.                                     ReturnToPreviousLink();
  1699.                                 }
  1700.                             else if (MenuItem == mWhoLinksToThisOne)
  1701.                                 {
  1702.                                     HiliteLinksToCurrent();
  1703.                                 }
  1704.                             else if (MenuItem == mShowCurrentItem)
  1705.                                 {
  1706.                                     ShowSpecifiedItem(CurrentlyHilited);
  1707.                                 }
  1708.                             else if (MenuItem == mGetFileInfo)
  1709.                                 {
  1710.                                     ShowFileInfoForSelection(CurrentlyHilited);
  1711.                                 }
  1712.                             else if (MenuItem == mFind)
  1713.                                 {
  1714.                                     if (DoStringDialog("Search for:",&SearchKey,
  1715.                                         mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
  1716.                                         {
  1717.                                             CurrentlyHilited = NIL;
  1718.                                             Find();
  1719.                                         }
  1720.                                 }
  1721.                             else if (MenuItem == mFindAgain)
  1722.                                 {
  1723.                                     Find();
  1724.                                 }
  1725.                             else
  1726.                                 {
  1727.                                     EXECUTE(PRERR(AllowResume,"main:  Unknown menu command"));
  1728.                                 }
  1729.                             break;
  1730.                         case eWindowClosing:
  1731.                             ContinueFlag = False;
  1732.                             break;
  1733.                         case eWindowResized:
  1734.                             /* clear the area */
  1735.                          WindowSizeChangedPoint:
  1736.                             SetClipRect(Window,0,0,GetWindowWidth(Window),GetWindowHeight(Window));
  1737.                             DrawBoxErase(Window,0,0,GetWindowWidth(Window),GetWindowHeight(Window));
  1738.                             /* resize scrollbars */
  1739.                             SetScrollLocation(VerticalScroll,GetWindowWidth(Window) - 15,
  1740.                                 LeadingSpace - 1,GetWindowHeight(Window) + 2 - LeadingSpace - 15);
  1741.                             SetScrollLocation(HorizontalScroll,-1,GetWindowHeight(Window) - 15,
  1742.                                 GetWindowWidth(Window) + 2 - 15);
  1743.                             SetMaxScrollIndex(VerticalScroll,TotalHeight - (GetWindowHeight(Window)
  1744.                                 - LeadingSpace - 15) + 1);
  1745.                             SetScrollIndex(VerticalScroll,CurrentYIndex);
  1746.                             SetMaxScrollIndex(HorizontalScroll,TotalWidth
  1747.                                 - (GetWindowWidth(Window) - 15) + 1);
  1748.                             SetScrollIndex(HorizontalScroll,CurrentXIndex);
  1749.                             /* move the button */
  1750.                             /* redraw everything */
  1751.                             UpdateProcedure(NIL);
  1752.                             break;
  1753.                         case eActiveWindowChanged:
  1754.                             if (EWin == Window)
  1755.                                 {
  1756.                                     EnableScrollBar(VerticalScroll);
  1757.                                     EnableScrollBar(HorizontalScroll);
  1758.                                 }
  1759.                              else
  1760.                                 {
  1761.                                     DisableScrollBar(VerticalScroll);
  1762.                                     DisableScrollBar(HorizontalScroll);
  1763.                                 }
  1764.                             SetClipRect(Window,0,0,GetWindowWidth(Window),GetWindowHeight(Window));
  1765.                             DrawBitmap(Window,GetWindowWidth(Window) - 15,GetWindowHeight(Window) - 15,
  1766.                                 GetGrowIcon(EWin == Window));
  1767.                             break;
  1768.                     }
  1769.             }
  1770.  
  1771.      AwwSkipit:
  1772.         /* application cleanup */
  1773.         ClearStartupDocuments();
  1774.         DisposeScrollBar(VerticalScroll);
  1775.         DisposeScrollBar(HorizontalScroll);
  1776.         KillWindow(Window);
  1777.         DisposeAliasList();
  1778.         DisposeList(GlobalList);
  1779.         ReleasePtr(SearchKey);
  1780.         KillMenuAndDeleteItems(mmAppleMenu);
  1781.         KillMenuAndDeleteItems(mmFileMenu);
  1782.         KillMenuAndDeleteItems(mmEditMenu);
  1783.  
  1784.         /* level 1 cleanup */
  1785.         ShutdownGrowIcon();
  1786.         ShutdownAlertSubsystem();
  1787.  
  1788.         /* level 0 cleanup */
  1789.         ShutdownScreen();
  1790.  
  1791.      TotalFailureEscapePoint:
  1792.         APRINT(("-main"));
  1793.         return 0;
  1794.     }
  1795.